home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / apps / 21 / emacsrc / search.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-05-14  |  6.4 KB  |  268 lines

  1. /*
  2.  * The functions in this file implement commands that search in the forward
  3.  * and backward directions. There are no special characters in the search
  4.  * strings. Probably should have a regular expression search, or something
  5.  * like that.
  6.  *
  7.  * REVISION HISTORY:
  8.  *
  9.  * ? Steve Wilhite, 1-Dec-85     - massive cleanup on code.
  10.  *   prabhaker mateti, 3/2/86,   - ^S/^R in search to next forw/backsearch
  11.  */
  12.  
  13. #include        "ed.h"
  14.  
  15. static char    NOTFOUND[] = "Not found";
  16.  
  17. /*
  18.  * Search forward. Get a search string from the user, and search, beginning at
  19.  * ".", for the string. If found, reset the "." to be just after the match
  20.  * string, and [perhaps] repaint the display. Bound to "C-S".
  21.  */
  22. forwsearch(f, n)
  23.     {
  24.     register int s;
  25.  
  26.     s = readpattern("Forward Search");
  27.     if ((s == ABORT) || (s == FALSE))  return (s);
  28.     if (s == 0x12) return (bsearch(f, n));
  29.     return(fsearch(f, n));
  30. }
  31.  
  32.  
  33. fsearch(f, n)
  34.     {
  35.     register LINE *clp;
  36.     register int cbo;
  37.     register LINE *tlp;
  38.     register int tbo;
  39.     register int c;
  40.     register char *pp;
  41.  
  42.     clp = curwp->w_dotp;
  43.     cbo = curwp->w_doto;
  44.  
  45.     while (clp != curbp->b_linep)
  46.         {
  47.         if (cbo == llength(clp))
  48.             {
  49.             clp = lforw(clp);
  50.             cbo = 0;
  51.             c = '\n';
  52.             }
  53.         else
  54.             c = lgetc(clp, cbo++);
  55.  
  56.         if (eq(c, pat[0]) != FALSE)
  57.             {
  58.             tlp = clp;
  59.             tbo = cbo;
  60.             pp  = &pat[1];
  61.  
  62.             while (*pp != 0)
  63.                 {
  64.                 if (tlp == curbp->b_linep)
  65.                     goto fail;
  66.  
  67.                 if (tbo == llength(tlp))
  68.                     {
  69.                     tlp = lforw(tlp);
  70.                     tbo = 0;
  71.                     c = '\n';
  72.                     }
  73.                 else
  74.                     c = lgetc(tlp, tbo++);
  75.  
  76.                 if (eq(c, *pp++) == FALSE)
  77.                     goto fail;
  78.                 }
  79.  
  80.             curwp->w_dotp  = tlp;
  81.             curwp->w_doto  = tbo;
  82.             curwp->w_flag |= WFMOVE;
  83.             return (TRUE);
  84.             }
  85. fail:;
  86.         }
  87.  
  88.     mlwrite(NOTFOUND);
  89.     return (FALSE);
  90.     }
  91.  
  92. /*
  93.  * Reverse search. Get a search string from the user, and search, starting at
  94.  * "." and proceeding toward the front of the buffer. If found "." is left
  95.  * pointing at the first character of the pattern [the last character that was
  96.  j matched]. Bound to "C-R".
  97.  */
  98. backsearch(f, n)
  99.     {
  100.     register int s;
  101.  
  102.     s = readpattern("Backward Search");
  103.     if ((s == ABORT) || (s == FALSE))  return (s);
  104.     if (s == 0x13) return (fsearch(f, n));
  105.     return(bsearch(f, n));
  106. }
  107.  
  108.  
  109. bsearch(f, n)
  110.     {
  111.     register LINE *clp;
  112.     register int cbo;
  113.     register LINE *tlp;
  114.     register int tbo;
  115.     register int c;
  116.     register char *epp;
  117.     register char *pp;
  118.  
  119.     for (epp = &pat[0]; epp[1] != 0; ++epp)
  120.         ;
  121.  
  122.     clp = curwp->w_dotp;
  123.     cbo = curwp->w_doto;
  124.  
  125.     for (;;)
  126.         {
  127.         if (cbo == 0)
  128.             {
  129.             clp = lback(clp);
  130.  
  131.             if (clp == curbp->b_linep)
  132.                 {
  133.                 mlwrite(NOTFOUND);
  134.                 return (FALSE);
  135.                 }
  136.  
  137.             cbo = llength(clp)+1;
  138.             }
  139.  
  140.         if (--cbo == llength(clp))
  141.             c = '\n';
  142.         else
  143.             c = lgetc(clp, cbo);
  144.  
  145.         if (eq(c, *epp) != FALSE)
  146.             {
  147.             tlp = clp;
  148.             tbo = cbo;
  149.             pp  = epp;
  150.  
  151.             while (pp != &pat[0])
  152.                 {
  153.                 if (tbo == 0)
  154.                     {
  155.                     tlp = lback(tlp);
  156.                     if (tlp == curbp->b_linep)
  157.                         goto fail;
  158.  
  159.                     tbo = llength(tlp)+1;
  160.                     }
  161.  
  162.                 if (--tbo == llength(tlp))
  163.                     c = '\n';
  164.                 else
  165.                     c = lgetc(tlp, tbo);
  166.  
  167.                 if (eq(c, *--pp) == FALSE)
  168.                     goto fail;
  169.                 }
  170.  
  171.             curwp->w_dotp  = tlp;
  172.             curwp->w_doto  = tbo;
  173.             curwp->w_flag |= WFMOVE;
  174.             return (TRUE);
  175.             }
  176. fail:;
  177.         }
  178.     }
  179.  
  180. /*
  181.  * Compare two characters. The "bc" comes from the buffer. It has it's case
  182.  * folded out. The "pc" is from the pattern.
  183.  */
  184. eq(bc, pc)
  185.     int bc;
  186.     int pc;
  187.     {
  188.     if (bc>='a' && bc<='z')
  189.         bc -= 0x20;
  190.  
  191.     if (pc>='a' && pc<='z')
  192.         pc -= 0x20;
  193.  
  194.     if (bc == pc)
  195.         return (TRUE);
  196.  
  197.     return (FALSE);
  198.     }
  199.  
  200. /*
  201.  * Read a pattern. Stash it in the external variable "pat". The "pat" is not
  202.  * updated if the user types in an empty line. If the user typed an empty line,
  203.  * and there is no old pattern, it is an error. Display the old pattern, in the
  204.  * style of Jeff Lomicka. There is some do-it-yourself control expansion.
  205.  * Returns: ABORT, TRUE, FALSE, FORWARD, REVERSE
  206.  */
  207. readpattern(prompt)
  208.     char *prompt;
  209.     {
  210.     register char *cp1;
  211.     register char *cp2;
  212.     register int c;
  213.     register int s;
  214.     register int i;
  215.     char tpat[NPAT+20];
  216.  
  217.     cp1 = &tpat[0];                     /* Copy prompt */
  218.     cp2 = prompt;
  219.  
  220.     while ((c = *cp2++) != '\0')
  221.         *cp1++ = c;
  222.  
  223.     if (pat[0] != '\0')                 /* Old pattern */
  224.         {
  225.         *cp1++ = ' ';
  226.         *cp1++ = '[';
  227.         cp2 = &pat[0];
  228.  
  229.         while ((c = *cp2++) != 0)
  230.             {
  231.             if (cp1 < &tpat[NPAT+20-6]) /* "??]: \0" */
  232.                 {
  233.                 if (c<0x20 || c==0x7F) {
  234.                     *cp1++ = '^';
  235.                     c ^= 0x40;
  236.                     }
  237.                 else if (c == '%')      /* Map "%" to */
  238.                     *cp1++ = c;         /* "%%". */
  239.  
  240.                 *cp1++ = c;
  241.                 }
  242.             }
  243.  
  244.         *cp1++ = ']';
  245.         }
  246.  
  247.     *cp1++ = ':';                       /* Finish prompt */
  248.     *cp1++ = ' ';
  249.     *cp1++ = '\0';
  250.     s = mlreply(tpat, tpat, NPAT);      /* Read pattern */
  251.  
  252.     if (s == TRUE)                      /* Specified */
  253.     {
  254.     i = strlen(tpat);        /* i will be > 0, because mlreply */
  255.     c = tpat[i-1];            /* was true */
  256.     if ((c == 0x12) || (c == 0x13)) {
  257.        tpat[--i] = (char) 0;
  258.        s = c;
  259.     }
  260.         if (i > 0) strcpy(pat, tpat);
  261.     } else if (s == FALSE && pat[0] != 0)         /* CR, but old one */
  262.         s = TRUE;
  263.  
  264.     return (s);
  265.     }
  266.  
  267. /* -eof- */
  268.